package com.mc.mcgoweb.thread.threadinterrupt;

public class ThreadService {
    private Thread executeThread;
    private boolean finished = false;

    /**
     * 场景:开启多线程执行任务的时候，如果内部逻辑由于各种原因导致执行很慢，比如之前的业务逻辑只需要3秒钟，现在执行了3分钟都还没结束
     * 那么我们代码中必须手动结束该线程，释放资源。
     * 实现:可以考虑使用父类线程里面嵌套子类线程,子类线程设置为守护线程daemon，子线程join住，设置个标记finished。
     * 如果执行完成后标记相应设置为true;
     * 使用daemon原因:如果父类线程中断了，那么子类线程也相应中断。
     * 使用join原因:可以让子类线程一直执行任务直至结束，父类线程才会开始执行
     * 提供一个shutdown(long mills)方法,调用该方法：如果该线程未在我们预期的时间内结束，那么就会主动调用父类线程的中断方法interrupt()
     * 随着主线程的结束，那么子线程因为是daemon，子线程也相应结束。
     * 如果比预期时间端，那么子线程执行结束后，主线程执行结束后，线程会自动释放，我们无需考虑。
     *
     * @param task
     */

    public void execute(Runnable task) {
        executeThread = new Thread() {
            @Override
            public void run() {
                Thread runner = new Thread(task);
                runner.setDaemon(true);
                runner.start();
                try {
                    runner.join();
                    finished = true;
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        };
        executeThread.start();

    }

    public void shutdown(long mills) {
        long now = System.currentTimeMillis();
        while (!finished) {
            //finished还是false 证明线程runner还没执行结束
            if ((System.currentTimeMillis() - now >= mills)) {
                System.out.println("执行超时！");
                executeThread.interrupt();
                break;
            }
            try {
                executeThread.sleep(1);
            } catch (InterruptedException e) {
                System.out.println("主线程被打断！");
            }

        }

    }
}
